package com.heima.comment.service.impl;

import com.heima.comment.dtos.CommentSaveDto;
import com.heima.comment.pojos.ApComment;
import com.heima.comment.pojos.ApCommentLike;
import com.heima.comment.pojos.CommentVo;
import com.heima.comment.service.CommentHotService;
import com.heima.comment.service.CommentService;
import com.heima.feigns.user.UserFeign;
import com.heima.model.comment.dtos.CommentDto;
import com.heima.model.comment.dtos.CommentLikeDto;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.common.enums.AppHttpCodeEnum;
import com.heima.model.user.pojos.ApUser;
import com.heima.utils.threadlocal.AppThreadLocalUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @Description:
 * @Version: V1.0
 */
@Service
@Slf4j
public class CommentServiceImpl implements CommentService {

    @Autowired
    UserFeign userFeign;

    @Autowired
    MongoTemplate mongoTemplate;

    private final Integer size = 10;

    /**
     * 保存文章评论
     *
     * @param dto
     * @return
     */
    @Override
    public ResponseResult saveComment(CommentSaveDto dto) {
        //1 参数校验
        if (dto==null || dto.getArticleId()==null
                || StringUtils.isBlank(dto.getContent()) || dto.getContent().length()>140){
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID, "文章评论不合法");
        }

        //2 获取用户登录状态
        ApUser user = AppThreadLocalUtils.getUser();
        if (user == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.NEED_LOGIN);
        }
        // 获取用户的对象
        user = userFeign.findApUserById(user.getId());
        if (user == null || user.getStatus()) {
            return ResponseResult.errorResult(AppHttpCodeEnum.NEED_LOGIN,"当前用户不合法");
        }

        //3 封装数据，执行保存评论
        ApComment comment = ApComment.builder()
                .authorId(user.getId())
                .authorName(user.getName())
                .entryId(dto.getArticleId())
                .type((short) 0)
                .content(dto.getContent())
                .image(user.getImage())
                .likes(0)
                .reply(0)
                .flag(0)
                .createdTime(new Date())
                .build();
        mongoTemplate.save(comment);

        //4 返回结果
        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
    }


    @Autowired
    CommentHotService commentHotService;

    /**
     * 评论点赞
     * @param dto
     * @return
     */
    @Override
    public ResponseResult like(CommentLikeDto dto) {
        //1 参数校验
        if (dto == null || StringUtils.isBlank(dto.getCommentId())
                || dto.getOperation() < 0 || dto.getOperation() > 1) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }

        //2 获取用户登录状态
        ApUser user = AppThreadLocalUtils.getUser();
        if (user == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.NEED_LOGIN);
        }

        //3 判断当前评论是否存在
        ApComment apComment = mongoTemplate.findById(dto.getCommentId(), ApComment.class);
        if (apComment == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.DATA_NOT_EXIST);
        }

        //5 判断当前用户是否已点赞
        ApCommentLike apCommentLike = mongoTemplate.findOne(
                Query.query(Criteria
                .where("authorId").is(user.getId())
                .and("commentId").is(dto.getCommentId())
        ), ApCommentLike.class);

        if (apCommentLike != null && dto.getOperation() == 0) {
            return ResponseResult.errorResult(AppHttpCodeEnum.DATA_EXIST, "已点赞");
        }


        //4 点赞/取消点赞
        if (dto.getOperation() == 0) {  //点赞
            // 保存点赞
            ApCommentLike commentLike = new ApCommentLike();
            commentLike.setAuthorId(user.getId());
            commentLike.setCommentId(dto.getCommentId());
            commentLike.setOperation(dto.getOperation());
            mongoTemplate.save(commentLike);

            // 更新评论的点赞数 +1
            apComment.setLikes(apComment.getLikes() + 1);
            mongoTemplate.save(apComment);


            //*** 计算热点评论
            if (apComment.getLikes() >= 5 && apComment.getFlag() == 0) {
                log.info("***** 开始计算热点评论 *****");
                commentHotService.hotCommentExecutor(apComment.getEntryId(), apComment);
            }

        }else { // 取消点赞
            // 删除点赞
            Query query = Query.query(Criteria
                    .where("authorId").is(user.getId())
                    .and("commentId").is(dto.getCommentId())
            );
            mongoTemplate.remove(query, ApCommentLike.class);

            // 更新评论的点赞数 -1
            apComment.setLikes((apComment.getLikes() - 1 < 0) ? 0 : (apComment.getLikes() - 1));
            mongoTemplate.save(apComment);
        }

        //5 返回结果
        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
    }



    /**
     * 查询文章评论列表
     * @param dto
     * @return
     */
    @Override
    public ResponseResult load(CommentDto dto) {
        //1 参数校验
        if (dto == null || dto.getArticleId() == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }
        if (dto.getMinDate() == null) {
            dto.setMinDate(new Date());
        }

        //**************热点评论列表*****************
        List<ApComment> commentList = new ArrayList<>();

        if (dto.getIndex() == 1) {
            // 获取热点评论列表
            Query query1 = Query.query(Criteria.where("entryId").is(dto.getArticleId())
                    .and("type").is(0)
                    .and("flag").is(1));
            // 排序
            query1.with(Sort.by(Sort.Direction.DESC, "likes"));
            // 一页记录数
            query1.limit(5);
            commentList = mongoTemplate.find(query1, ApComment.class);

            if (commentList != null || commentList.size() > 0) { // 存在热点评论 5条

                int hsize = size - commentList.size();
                Query query2 = Query.query(Criteria.where("entryId").is(dto.getArticleId())
                        .and("type").is(0)
                        .and("flag").is(0)
                        .and("createdTime").lt(dto.getMinDate()));
                // 排序
                query2.with(Sort.by(Sort.Direction.DESC, "createdTime"));
                // 一页记录数
                query2.limit(hsize);
                List<ApComment> ptcomments = mongoTemplate.find(query2, ApComment.class);

                commentList.addAll(ptcomments);
            }else {
                Query query3 = Query.query(Criteria.where("entryId").is(dto.getArticleId())
                        .and("type").is(0)
                        .and("flag").is(0)
                        .and("createdTime").lt(dto.getMinDate()));
                // 排序
                query3.with(Sort.by(Sort.Direction.DESC, "createdTime"));
                // 一页记录数
                query3.limit(size);
                commentList = mongoTemplate.find(query3, ApComment.class);
            }

        } else {

            //2 根据文章id查询文章评论列表
            Query query4 = Query.query(Criteria
                    .where("entryId").is(dto.getArticleId())
                    .and("type").is(0)
                    .and("flag").is(0)
                    .and("createdTime").lt(dto.getMinDate())
            );
            // 排序
            query4.with(Sort.by(Sort.Direction.DESC, "createdTime"));
            // 一页记录数
            query4.limit(size);
            commentList = mongoTemplate.find(query4, ApComment.class);
        }

        //*******************************


        if (commentList == null || commentList.size() == 0) {
            return ResponseResult.okResult();
        }

        //3 获取用户登录状态
        ApUser user = AppThreadLocalUtils.getUser();
        //4 判断用户登录状态  未登录 直接返回评论列表
        if (user == null) {
            return ResponseResult.okResult(commentList);
        }

        //5 已登录， 回显当前用户是否对莫一条评论数据点赞
        //5.1 取所有评论id [1,2,4,5,6]
        List<String> idList = commentList.stream()
                .map(commment -> commment.getId()).collect(Collectors.toList());

        //5.2 查询当前评论id下的点赞列表 当前用点赞列表
       List<ApCommentLike> commentLikes = mongoTemplate.find( Query.query(Criteria
                                     .where("commentId").in(idList)
                                     .and("operation").is(0)
                                     .and("authorId").is(user.getId())
                             ) ,
                             ApCommentLike.class);

        //5.3 判断封装
        List<CommentVo> commentVos = new ArrayList<>();

        if(commentList!=null && commentList.size()>0 && commentLikes!=null && commentLikes.size()>0){
            commentList.forEach( comment -> {  // 所有的评论
                //***
                CommentVo commentVo = new CommentVo();
                BeanUtils.copyProperties(comment, commentVo);

                commentLikes.forEach( commentLike -> {
                    if (comment.getId().equals(commentLike.getCommentId())) {
                        // 该评论是我已点赞 回显 **
                        commentVo.setOperation(0);
                    }
                });

                // ** 添加到集合
                commentVos.add(commentVo);
            } );

        }else { // 对当前文章评论未点赞
            return ResponseResult.okResult(commentList);
        }


        return ResponseResult.okResult(commentVos);
    }
}
